// noinspection NonAsciiCharacters

import type { IBaseModuleTemplate } from '../lib/template'
import type { ConfigManager } from './config_manager'
import { HOSTNAME, logger } from '../types/constants'
import { SYMBOLS } from '../types/interfaces'
import { ConfigManager as ConfigManagerObject } from './config_manager'

interface IModuleStatusTable { 模块名称: string, 模块状态: string, 详细信息: string }

/**
 * 模块管理器（单例模式）
 */
export class ModuleManager {
  readonly name = 'ModuleManager'
  private modules: Map<string, IBaseModuleTemplate> = new Map()
  activeModules: Set<string> = new Set()
  protected configManager: ConfigManager
  private static instance: ModuleManager
  // 模块状态排序权重
  private moduleStatusOrder: Record<string, { label: string, weight: number }> = {
    SUCCESS: { label: `${SYMBOLS.COLOR_CIRCLES.GREEN} 成功`, weight: 1 },
    SKIPPED: { label: `${SYMBOLS.COLOR_CIRCLES.YELLOW} 跳过`, weight: 2 },
    ERROR: { label: `${SYMBOLS.COLOR_CIRCLES.RED} 失败`, weight: 3 },
  }

  constructor(manager: ConfigManager) {
    this.configManager = manager
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): ModuleManager {
    if (!ModuleManager.instance) {
      ModuleManager.instance = new ModuleManager(ConfigManagerObject.getInstance())
    }
    return ModuleManager.instance
  }

  /**
   * 注册模块
   * @param module 模块实例
   */
  registerModule(module: IBaseModuleTemplate): void {
    if (this.modules.has(module.name)) {
      logger.warn(`[${this.name}] Module ${module.name} already registered`)
      return
    }
    this.modules.set(module.name, module)
  }

  /**
   * 批量注册模块
   * @param modules 模块实例数组
   */
  registerModules(modules: IBaseModuleTemplate[]): void {
    modules.forEach(module => this.registerModule(module))
  }

  /**
   * 初始化模块（仅支持已注册模块）
   * @param moduleName 模块名称
   * @param condition 前置条件
   */
  async initModule(moduleName: string, condition?: boolean | ((...args: any[]) => boolean)): Promise<void> {
    const isInitialized = this.checkModuleInitialized(moduleName, condition || true)
    if (isInitialized)
      return

    const isRegistered = this.modules.has(moduleName)
    const module = this.modules.get(moduleName)
    if (isRegistered && module) {
      await module.init()
      this.activeModules.add(moduleName)
    }
  }

  /**
   * 初始化匹配当前域名的模块
   */
  async initModules(): Promise<{
    total: number
    success: number
    skipped: number
    errors: number
  }> {
    if (!this.configManager) {
      throw new Error(`ConfigManager 未设置`)
    }

    const initTasks = Array.from(this.modules.entries()).map(
      async ([name, module]) => {
        try {
          // 并行执行检查逻辑
          const [isSupported, featureId] = await Promise.all([
            // 1. 检查模块是否支持当前域名
            Promise.resolve(module.supportedPlatforms?.includes(HOSTNAME)),
            // 2. 检查配置是否启用（通过模块名查找对应功能ID）
            Promise.resolve(this.configManager!.getFeatureIdValueForModule(name)),
          ])

          const isEnabled = featureId
            ? this.configManager.getFeatureEnabled(featureId)
            : true

          // 记录支持但配置未启用的模块
          if (isSupported && !isEnabled) {
            this.activeModules.add(name)
          }

          if (isSupported && isEnabled) {
            // 这里与 FeatureToggle 类的 setFeatureStates 方法重复，注释掉，避免重复初始化
            // await module.init()
            return { name, status: 'success' as const }
          }
          else {
            const reasons = [
              !isSupported && '不支持当前平台',
              !isEnabled && '配置未启用',
            ].filter(Boolean) as string[]
            return {
              name,
              status: 'skipped' as const,
              reason: reasons.join(' | '),
            }
          }
        }
        catch (error: any) {
          logger.error(`[${this.name}] 模块 '${name}' 加载失败`, error)
          return {
            name,
            status: 'error' as const,
            error: error instanceof Error ? error : new Error(String(error)),
          }
        }
      },
    )

    // 并行执行所有初始化任务
    const results = await Promise.allSettled(initTasks)
    // 处理结果
    const initResults = {
      success: [] as string[],
      skipped: [] as { name: string, reason: string }[],
      errors: [] as { name: string, error: Error }[],
    }

    results.forEach((result) => {
      if (result.status === 'fulfilled') {
        const { name, status } = result.value
        if (status === 'success') {
          this.activeModules.add(name)
          initResults.success.push(name)
        }
        else if (status === 'skipped') {
          initResults.skipped.push({
            name,
            reason: result.value.reason,
          })
        }
        else {
          initResults.errors.push({
            name,
            error: result.value.error,
          })
        }
      }
      else {
      // 理论上不会进入这里，因为initTasks已经处理了错误
        logger.error(`[${this.name}] 未知的加载错误`, result.reason)
      }
    })

    if (initResults.success.length > 0 || initResults.skipped.length > 0 || initResults.errors.length > 0) {
      // 准备表格数据
      const tableData: IModuleStatusTable[] = []

      // 添加成功模块
      initResults.success.forEach((name) => {
        tableData.push({
          模块名称: name,
          模块状态: this.moduleStatusOrder.SUCCESS.label,
          详细信息: '加载完成',
        })
      })

      // 添加跳过模块
      initResults.skipped.forEach(({ name, reason }) => {
        tableData.push({
          模块名称: name,
          模块状态: this.moduleStatusOrder.SKIPPED.label,
          详细信息: reason,
        })
      })

      // 添加失败模块
      initResults.errors.forEach(({ name, error }) => {
        tableData.push({
          模块名称: name,
          模块状态: this.moduleStatusOrder.ERROR.label,
          详细信息: error.message,
        })
      })

      // 按状态排序表格数据
      tableData.sort((a, b) => {
        const aWeight = this.getModuleWeight(a.模块状态)
        const bWeight = this.getModuleWeight(b.模块状态)
        return aWeight - bWeight || a.模块名称.localeCompare(b.模块名称)
      })

      logger.important(`${SYMBOLS.UI.CHART} 模块加载结果 (总计: ${this.modules.size}, 成功: ${initResults.success.length}, 跳过: ${initResults.skipped.length}, 失败: ${initResults.errors.length})`, tableData)
      // logger.table(`${SYMBOLS.UI.CHART} 模块加载结果 (总计: ${this.modules.size}, 成功: ${initResults.success.length}, 跳过: ${initResults.skipped.length}, 失败: ${initResults.errors.length})`, tableData)
    }

    // 返回初始化结果统计
    return {
      total: this.modules.size,
      success: initResults.success.length,
      skipped: initResults.skipped.length,
      errors: initResults.errors.length,
    }
  }

  /**
   * 销毁所有活动模块
   */
  async destroyModules(): Promise<void> {
    for (const name of this.activeModules) {
      const module = this.modules.get(name)
      if (module) {
        await module.destroy()
        this.activeModules.delete(name)
        logger.info(`[${this.name}] Destroyed module: ${name}`)
      }
    }
  }

  /**
   * 获取模块实例
   * @param name 模块名称
   */
  getModule<T extends IBaseModuleTemplate>(name: string): T | undefined {
    return this.modules.get(name) as T
  }

  /**
   * 检查模块是否已初始化
   * @param name 模块名称
   * @param condition 前置条件
   */
  checkModuleInitialized(name: string, condition: boolean | ((...args: any[]) => boolean)): boolean {
    // 检查模块是否激活
    const isInitialized = this.activeModules.has(name)

    // 如果没有提供条件，仅检查初始化状态
    if (condition === undefined)
      return isInitialized

    // 处理函数类型的条件
    if (typeof condition === 'function') {
      try {
        return isInitialized && condition()
      }
      catch (error: any) {
        logger.error(`[${this.name}] 检查模块条件失败 [${name}]`, error)
        return false
      }
    }

    // 处理布尔类型的条件
    return isInitialized && condition
  }

  /**
   * 获取模块状态的权重
   */
  private getModuleWeight(label: string): number {
    return Object.values(this.moduleStatusOrder)
      .find(item => item.label === label)
      ?.weight || 0
  }
}
